import time
import sys
import util
def encode(P, senderid, senderpriv, nsender, receiverpub, nreceiver):
    S=msgmaker(P, senderid,senderpriv, nsender)
    Y=encodepackage(S, receiverpub, nreceiver)
    A=wrapall(Y,receiverpub, nreceiver)
    return A


def msgmaker(P, senderid, senderpriv, nsender):
    S=''
    Header = makeheader(senderpriv, nsender)
    S+=str(Header)+" "
    S+=(senderid+ " ")
    Time=time.ctime(time.time())
    S+=(Time+ " ")
    S+=(P)
    return S

def encodepackage(S, e, n):
    E=[]
    bignumber=[]
    newmsg=S
    length = len(newmsg)
    while(len(newmsg)%32 !=0):
        newmsg= newmsg+' '
    counter=0
    while(counter*32<len(newmsg)):
        for s in newmsg[counter*32:(counter+1)*32]:
            num=ord(s)
            if num<100:
                bignumber.append('0'+str(num))
            else:
                bignumber.append(str(num))
        bignum='1'+''.join(bignumber)
        msgcryp = mod_exp(int(bignum), e, n)
        E.append(msgcryp)
        bignum=''
        bignumber=[]
        counter+=1
    return E

def wrapall(Y, receiverpub, nreceiver):
    A=[]
    Time=time.time()
    A.append(Time)
    A.append((receiverpub, nreceiver))
    A.append(Y)
    return A

def makeheader(e, n):
    H=[]
    bignumber=[]
    header='HeaderHelloWorld'
    for h in header:
        num=ord(h)
        if num<100:
            bignumber.append('0'+str(num))
        else:
            bignumber.append(str(num))
    bignum='1'+''.join(bignumber)
    headercryp = mod_exp(int(bignum), e, n)
    H.append(headercryp)
    return H


def mod_exp(a, e, N):
  x = 1
  while e > 0:
    if e & 1:    
      x = (x * a) % N
    a = (a * a) % N
    e = e>>1
  return x

#def mod_exp(a, e, N):
#    if e == 1:
#        return a % N
#    if e % 2 ==1 :
#        return (a*(mod_exp(a, (e-1)/2, N)**2))%N
#    else:
#        return (mod_exp(a, e/2, N)**2) % N

def decode(C, receiverpriv, nreceiver):
    counter=0
    msg=''
    for c in C:
        de=[]
        de2=[]
        line=''
        decrypt=0
        decryptstr=''
        cint = int(c)
        decrypt= mod_exp(cint, receiverpriv,nreceiver)
        decryptstr=str(decrypt)
        decryptstr= decryptstr[1:]
        letters = len(decryptstr)/3
        for i in range (0,letters):
            de.append(decryptstr[i*3:(i+1)*3])
        for d in de:
            de2.append(chr(int(d)))
        counter+=1
        line= ''.join(de2)
        msg+=line
    loc1 = msg.find('[')
    loc2 = msg.find(']')
    header = msg[loc1+1:loc2-1]
    body = msg[loc2+2:]
    loc3 = body.find(' ')
    sender = body[:loc3]
    restofbody = body[loc3+1:]
    headerint = int(header)
    pk = util.get_public_key(sender)
    if pk:
#   if(book.has_key(sender)):
#       print 'i know this person'
        senderpub = pk['e'] #book.get(sender)[0]
        sendern = pk['n'] #book.get(sender)[1]
        real=decodeheader(headerint, senderpub, sendern)
        if(real):
            return 'From [%s]:\n%s' % (sender, restofbody)
#            print 'Sender is '+sender
        else:
            return 'Claimed from [%s] but validation failed:\n%s' % (sender, restofbody)
#            print 'Sender is not '+sender+'. Fake messenge.'
#        print restofbody
    else:
        return 'Can not verify the sender [%s]\n%s' % (sender, restofbody)
#       print 'I dont know this person'
#       print restofbody

def decodeheader(H, d, n):
  try:
    header=[]
    headerexpected='HeaderHelloWorld'
    h = mod_exp(H, d, n)
    hstr = str(h)
    hstr = hstr[1:]
    for i in range(0,len(hstr)/3):
        header.append(chr(int(hstr[i*3:(i+1)*3])))
    headerdecoded=''.join(header)
    if headerdecoded==headerexpected:
        return True
    else:
        return False
  except:
    return False
